//package com.laiketui.payment.service.impl;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.google.common.collect.Maps;
//import com.laiketui.common.api.PublicOrderService;
//import com.laiketui.common.api.PubliceService;
//import com.laiketui.common.api.openUser.OpenUserService;
//import com.laiketui.common.config.wechatpay.WechatConfigInfo;
//import com.laiketui.common.mapper.*;
//import com.laiketui.common.utils.tool.HttpApiUtils;
//import com.laiketui.common.utils.tool.cache.RedisDataTool;
//import com.laiketui.common.utils.weixin.AppletUtil;
//import com.laiketui.core.cache.RedisUtil;
//import com.laiketui.core.exception.LaiKeAPIException;
//import com.laiketui.core.lktconst.GloabConst;
//import com.laiketui.core.utils.help.SpringHelper;
//import com.laiketui.core.utils.tool.DataUtils;
//import com.laiketui.core.utils.tool.IpUtil;
//import com.laiketui.core.utils.tool.WxOpenIdUtils;
//import com.laiketui.domain.lktconst.DictionaryConst;
//import com.laiketui.domain.lktconst.ErrorCode;
//import com.laiketui.domain.message.TemplateData;
//import com.laiketui.domain.order.NoticeModel;
//import com.laiketui.domain.order.OrderDataModel;
//import com.laiketui.domain.order.OrderDetailsModel;
//import com.laiketui.domain.order.OrderModel;
//import com.laiketui.domain.presell.PreSellGoodsModel;
//import com.laiketui.domain.presell.PreSellRecordModel;
//import com.laiketui.domain.user.User;
//import com.laiketui.domain.vo.MainVo;
//import com.laiketui.domain.vo.pay.PaymentVo;
//
//import com.laiketui.order.OrderParentNoSeq;
//import com.laiketui.order.api.enums.OrderParentMessageType;
//import com.laiketui.order.api.enums.OrderParentStatusEnum;
//import com.laiketui.order.api.enums.PayTypeEnum;
//import com.laiketui.order.domain.OrderParent;
//import com.laiketui.order.mapper.OrderParentMapper;
//import com.laiketui.order.service.OrderParentMessageService;
//import com.laiketui.order.service.OrderParentService;
//import com.laiketui.order.service.pay.BalancePayService;
//import com.laiketui.order.service.pay.impl.BalancePayServiceImpl;
//import com.laiketui.payment.api.WechatPayService;
//import com.laiketui.payment.common.AppConst;
//import com.laiketui.payment.params.PaymentParams;
//import com.laiketui.payment.service.dubbo.PayServiceAdapter;
//import com.laiketui.payment.util.WechatPayUtils;
//import com.laiketui.root.annotation.DubboApiMethod;
//import com.laiketui.root.annotation.HttpApiMethod;
//import github.wxpay.sdk.WXPay;
//import github.wxpay.sdk.WXPayConstants;
//import github.wxpay.sdk.WXPayUtil;
//import org.apache.commons.collections.MapUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.commons.lang3.time.FastDateFormat;
//import org.apache.dubbo.config.annotation.DubboService;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.http.MediaType;
//import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;
//import org.springframework.validation.annotation.Validated;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.annotation.Resource;
//import javax.servlet.http.HttpServletRequest;
//import java.math.BigDecimal;
//import java.net.URLDecoder;
//import java.net.URLEncoder;
//import java.util.*;
//
//import static com.laiketui.core.lktconst.DictionaryConst.OrdersType.*;
//import static com.laiketui.domain.lktconst.DictionaryConst.OrderPayType.*;
//import static com.laiketui.domain.lktconst.ErrorCode.BizErrorCode.*;
//
//@Service
//public class WechatPayServiceImpl extends PayServiceAdapter implements WechatPayService {
//
//    private final Logger logger = LoggerFactory.getLogger(WechatPayServiceImpl.class);
//
//    @Autowired
//    private UserMapper userMapper;
//
////    @Autowired
////    private RedisUtil redisUtil;
//
//    @Autowired
//    private PaymentConfigModelMapper paymentConfigModelMapper;
//
//    @Autowired
//    private OrderModelMapper orderModelMapper;
//
//    @Autowired
//    private OrderDetailsModelMapper orderDetailsModelMapper;
//
//    @Autowired
//    private OrderDataModelMapper orderDataModelMapper;
//
////    @Autowired
////    private PublicOrderService publicOrderService;
//
//    @Autowired
//    private ConfigModelMapper configModelMapper;
//
//    @Autowired
//    private NoticeModelMapper noticeModelMapper;
//
//    @Autowired
//    private PreSellRecordModelMapper preSellRecordModelMapper;
//
//    @Autowired
//    private PreSellGoodsMapper preSellGoodsMapper;
//
//    @Autowired
//    private UserBaseMapper userBaseMapper;
//
//    @Autowired
//    private OrderParentMapper orderParentMapper;
//
//    @Autowired
//    private OrderParentMessageService orderParentMessageService;
//
//    @Autowired
//    private OrderParentService orderParentService;
//
//    @Autowired
//    private OpenUserService openUserService;
//
////    @Value("${node.wx-certp12-path}")
////    private String path;
//
////    @Autowired
////    private PubliceService publiceService;
//
////    @Autowired
////    private HttpApiUtils httpApiUtils;
//
////    @Autowired
////    private OrderParentService orderParentService;
//
//    @Override
//    public Map<String, Object> wechatAppPay(Map<String, Object> params) throws LaiKeAPIException {
//        return null;
//    }
//
//    @Override
//    public Map<String, Object> weChatWapPay(Map<String, Object> params) throws LaiKeAPIException {
//        return null;
//    }
//
//    @Override
//    public Map<String, Object> wechatPcQrPay(Map<String, Object> params) throws LaiKeAPIException {
//        return null;
//    }
//
//    @Override
//    public Map<String, Object> wechatMiniPay(Map<String, Object> params) throws LaiKeAPIException {
//        return null;
//    }
//
//    @Override
//    public Map<String, Object> wechatJsapiPay(Map<String, Object> params) throws LaiKeAPIException {
//        return null;
//    }
//
//    @Override
//    public boolean MerchantTransfersToChange(String paramJson) throws LaiKeAPIException {
//        return false;
//    }
//
//    @Override
//    public void QueryBatchTransferOrder(MainVo vo) {
//
//    }
//
//    /**
//     * 微信支付V2
//     *
//     * @param params
//     * @return
//     * @throws LaiKeAPIException
//     */
//    @DubboApiMethod(apiKey = "com.laike.payment.wechat.v2.pay",
//            login = true, module = AppConst.MODULE_NAME, version = "1.0.0")
//    @Transactional
//    @Override
//    public Map<String, String> pay(PaymentParams params) throws LaiKeAPIException {
//        Map<String,String> payData = new HashMap<>();
//        try {
//            User user = null;
//            RedisUtil redisUtil = SpringHelper.getBeanInfo(RedisUtil.class);
//            user = RedisDataTool.getRedisUserCache(params.getAccessId(), redisUtil, true);
//            String openid = openUserService.selectOpenidByUser(user, params.getStoreId());
//            if(StringUtils.isBlank(openid)){
//                throw new LaiKeAPIException("用户没有openid");
//            }
//            //母单号
//            //获取订单信息
//            OrderParentService orderParentService = SpringHelper.getBeanInfo(OrderParentService.class);
//            OrderParent orderParent = orderParentService.getOrderParent(params.getOrderParentNo());
//            Integer status = orderParent.getStatus();
//            if(!OrderParentStatusEnum.WAIT_PAY.getCode().equals(status)){
//                throw new LaiKeAPIException(ERROR_CODE_YFKQECFZF, "请勿重复支付!", "pay");
//            }
//            WechatConfigInfo config = getWechatConfigInfo(params);
//            WXPay wxpay = new WXPay(config);
//            logger.info("微信支付配置:{}",wxpay.toString());
//            //查看微信订单信息（返回结果示例）
//            /*<xml>
//            <return_code><![CDATA[SUCCESS]]></return_code>
//            <return_msg><![CDATA[OK]]></return_msg>
//            <result_code><![CDATA[SUCCESS]]></result_code>
//            <mch_id><![CDATA[1516978921]]></mch_id>
//            <appid><![CDATA[wx441f3b338ac30350]]></appid>
//            <device_info><![CDATA[]]></device_info>
//            <trade_state><![CDATA[NOTPAY]]></trade_state>
//            <total_fee>1</total_fee>
//            <out_trade_no><![CDATA[PS230911142035506610]]></out_trade_no>
//            <trade_state_desc><![CDATA[订单未支付]]></trade_state_desc>
//            <nonce_str><![CDATA[VuiOJC5YH94H861V]]></nonce_str>
//            <sign><![CDATA[E572BB4FCB140458A2720E1F5317621B]]></sign>
//            </xml>*/
//            Map<String, String> queryMap = Maps.newHashMap();
//            String payOrderNo = createPayOrderNo();
//            orderParent.setPayType(PayTypeEnum.WECHAT_PAY.getCode());
//            orderParent.setPayOrderNo(payOrderNo);
//            orderParentService.updateByOrderParentNo(orderParent.getOrderParentNo(),orderParent);
//            queryMap.put("appid", config.getAppID());
//            queryMap.put("mch_id", config.getMchID());
//            queryMap.put("out_trade_no", orderParent.getPayOrderNo());
//            queryMap.put("nonce_str", String.valueOf(System.currentTimeMillis()));
//            logger.info("签名参数", JSON.toJSONString(queryMap));
//            String querySign = WXPayUtil.generateSignature(queryMap, config.getKey(), WXPayConstants.SignType.MD5);
//            queryMap.put("sign", querySign);
//            Map<String, String> map = wxpay.orderQuery(queryMap);
//            //查看订单支付前的状态
//            logger.info("支付前订单号[" + orderParent.getOrderParentNo() + "],支付订单号[" + orderParent.getOrderParentNo() + "] 微信返回的状态结果：", JSON.toJSONString(map));
//            if ("SUCCESS".equals(MapUtils.getString(map, "result_code")) && !"NOTPAY".equals(MapUtils.getString(map, "trade_state"))) {
//                //没有支付的情况下更换支付订单号，重新拉支付
//                payOrderNo = createPayOrderNo();
//                orderParent.setPayOrderNo(payOrderNo);
//                orderParentService.updateByOrderParentNo(orderParent.getOrderParentNo(),orderParent);
//            } else if ("SUCCESS".equals(MapUtils.getString(map, "result_code")) && "SUCCESS".equals(MapUtils.getString(map, "trade_state"))) {
//                //重复支付问题
//                throw new LaiKeAPIException(ERROR_CODE_YFKQECFZF, "请勿重复支付!", "pay");
//            }
//            Map<String, String> data = Maps.newHashMap();
//            data.put("body", "采购商品");
//            data.put("out_trade_no", orderParent.getPayOrderNo());
//            data.put("device_info", "");
//            data.put("fee_type", "CNY");
//            data.put("total_fee", String.valueOf(orderParent.getPayPrice()));
//            //获取ip地址
//            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//            data.put("spbill_create_ip", IpUtil.getIpAddr(request));
//            data.put("notify_url", config.getNotifyUrl());
//            //支付类型
//            String payClass = params.getPayType();
//            String appId = config.getAppID();
//            String appSecret = config.getAppSecreKey();
//            switch (payClass) {
//                case ORDERPAYTYPE_MINI_WECHAT:
//                    data.put("trade_type", "JSAPI");
//                    data.put("openid", openid);
//                    break;
//                case ORDERPAYTYPE_JSAPI_WECHAT:
//                case ORDERPAYTYPE_PC_WECHAT:
//                case ORDERPAYTYPE_H5_WECHAT:
//                default:
//                    data.put("trade_type", "APP");
//                    break;
//            }
//            logger.info("微信支付请求参数{}", data);
//            Map<String, String> payResult = wxpay.unifiedOrder(data);
//            logger.info("微信支付 类型：{},结果结果:{}", payClass, JSONObject.toJSONString(payResult));
//            String resultCode = MapUtils.getString(payResult, "result_code");
//            String returnCode = MapUtils.getString(payResult, "return_code");
//            if ("SUCCESS".equalsIgnoreCase(resultCode) && "SUCCESS".equalsIgnoreCase(returnCode)) {
//                String time = String.valueOf((System.currentTimeMillis() / 1000));
//                switch (payClass) {
//                    case ORDERPAYTYPE_MINI_WECHAT:
//                        Map<String, String> tmp = new HashMap<>();
//                        tmp.put("appId", MapUtils.getString(payResult, "appid"));
//                        tmp.put("nonceStr", MapUtils.getString(payResult, "nonce_str"));
//                        tmp.put("signType", "MD5");
//                        tmp.put("package", "prepay_id=" + MapUtils.getString(payResult, "prepay_id"));
//                        tmp.put("timeStamp", time);
//                        String sign = WXPayUtil.generateSignature(tmp, config.getKey(), WXPayConstants.SignType.MD5);
//                        payData.put("timeStamp", time);
//                        payData.put("state", String.valueOf(1));
//                        payData.put("appid", MapUtils.getString(payResult, "appid"));
//                        payData.put("nonceStr", MapUtils.getString(payResult, "nonce_str"));
//                        payData.put("signType", "MD5");
//                        payData.put("package", "prepay_id=" + MapUtils.getString(payResult, "prepay_id"));
//                        payData.put("paySign", sign);
//                        payData.put("out_trade_no", orderParent.getPayOrderNo());
//                        break;
//                    case ORDERPAYTYPE_PC_WECHAT:
//                    case ORDERPAYTYPE_APP_WECHAT:
//                    case ORDERPAYTYPE_JSAPI_WECHAT:
//                        break;
////                    case ORDERPAYTYPE_H5_WECHAT:
////                        StringBuilder sb = new StringBuilder(MapUtils.getString(payResult, "mweb_url"));
////                        logger.error("微信mweb_url支付跳转链接-----------{}", sb);
////                        String h5Url = getH5Url(orderModel.getStore_id()) + "pages/pay/payResult?sNo=" + orderModel.getReal_sno() + "&payment_money=" + orderModel.getZ_price() + "&isH5=true";
////                        String gbk = URLEncoder.encode(h5Url, "GBK");
////                        logger.error("url编码后-------------{}", sb + "&redirect_url=" + gbk);
////                        payData.put("url", sb + "&redirect_url=" + gbk);
//////                        payData.put("url", sb.toString());
////                        payData.put("pay_type", payClass);
////                        payData.put("prepayid", MapUtils.getString(payResult, "prepay_id"));
////                        break;
//                    default:
//                        break;
//                }
//                logger.error("============================================微信唤醒支付成功");
//                return payData;
//
//            } else {
//                throw new LaiKeAPIException(ErrorCode.BizErrorCode.API_OPERATION_FAILED, "微信支付失败", "wechatJsapiPay");
////                resultMap.put("message", "支付失败");
////                resultMap.put("code", 500);
////                resultMap.put("message", "支付失败");
//            }
//
//        } catch (LaiKeAPIException l) {
//            logger.error("微信支付失败", l);
//            throw l;
//        } catch (Exception e) {
//            logger.error("微信支付 异常", e);
//            throw new LaiKeAPIException(ErrorCode.BizErrorCode.API_OPERATION_FAILED, "微信支付失败", "wechatJsapiPay");
//        }
//    }
//
//    /**
//     * 获取微信支付配置
//     *
//     * @param params
//     * @return
//     * @throws Exception
//     */
//    private WechatConfigInfo getWechatConfigInfo(PaymentParams params) throws Exception {
//        //微信app支付 默认app支付
//        String className = params.getPayType();
//        int storeId = params.getStoreId();
//        String paymentJson = paymentConfigModelMapper.getPaymentConfigInfo(storeId, className);
//        paymentJson = URLDecoder.decode(paymentJson, GloabConst.Chartset.UTF_8);
//        logger.info(className + "支付配置信息：" + paymentJson);
//        JSONObject payJson = JSONObject.parseObject(paymentJson);
//        String appID = payJson.getString("appid");
//        logger.info("appID:{}", appID);
//        String mchID = payJson.getString("mch_id");
//        logger.info("mchID:{}", mchID);
//        String key = payJson.getString("mch_key");
//        logger.info("key:{}", key);
////        String certPath = payJson.getString("cert_p12");
////        String certPath = "C:/Users/Administrator/Desktop/WeChatPay/lkt_cert/apiclient_cert.p12";
////        logger.info("certPath:{}", certPath);
//        String notifyUrl = payJson.getString("notify_url");
//        logger.info("notifyUrl:{}", notifyUrl);
//        String appSecreKey = payJson.getString("appsecret");
//        logger.info("appSecreKey:{}", appSecreKey);
//        return new WechatConfigInfo(appID, mchID, key, notifyUrl, appSecreKey);
//    }
//
//    //创建支付订单号
//    public String createPayOrderNo() {
//        try {
//            StringBuilder payOrderNo = new StringBuilder();
//            Random random = new Random();
//            payOrderNo.append(FastDateFormat.getInstance(GloabConst.TimePattern.YMDHMS2).format(new Date())).append(random.nextInt(9))
//                    .append(random.nextInt(9)).append(random.nextInt(9)).append(random.nextInt(9))
//                    .append(random.nextInt(9)).append(random.nextInt(9));
//            OrderParent orderParent = new OrderParent();
//            orderParent.setPayOrderNo(payOrderNo.toString());
//            LambdaQueryWrapper<OrderParent> queryWrapper = new LambdaQueryWrapper<>();
//            queryWrapper.eq(OrderParent::getPayOrderNo,payOrderNo);
//            orderParent = orderParentMapper.selectOne(queryWrapper);
//            if(orderParent == null){
//                return payOrderNo.toString();
//            }else{
//                return createPayOrderNo();
//            }
//        } catch (Exception e) {
//            logger.error("创建订单号 异常", e);
//            throw new LaiKeAPIException(ErrorCode.BizErrorCode.ERROR_CODE_CJDDHSB, "创建订单号失败", "createOrderNo");
//        }
//    }
//
//    @Override
//    @Transactional
//    public String weChatNotifyV2(HttpServletRequest request) throws LaiKeAPIException{
//        try {
//            /**微信返回的请求体*/
//            Map params = Maps.newHashMap();
//            String notifyXml = WechatPayUtils.getRequestBody(request);
//            logger.info("微信回调结果：{}", notifyXml);
//            String weChatXml = request.getParameter("weChat_xml");
//            logger.info(weChatXml);
//            if (StringUtils.isEmpty(weChatXml) && !StringUtils.isEmpty(notifyXml)) {
//                weChatXml = notifyXml;
//            }
//            /**
//             * https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3
//             */
//            Map<String, String> notifyMap = WXPayUtil.xmlToMap(weChatXml);
//            String returnCode = MapUtils.getString(notifyMap, "return_code");
//            String resultCode = MapUtils.getString(notifyMap, "result_code");
//            String returnMsg = MapUtils.getString(notifyMap, "return_msg");
//            if (WXPayConstants.SUCCESS.equals(returnCode) && WXPayConstants.SUCCESS.equals(resultCode)) {
//                String payNo = MapUtils.getString(notifyMap, "out_trade_no");
//                params.put("appid", MapUtils.getString(notifyMap, "appid"));
//                params.put("mchID", MapUtils.getString(notifyMap, "mch_id"));
//                params.put("payNo", payNo);
//                LambdaQueryWrapper<OrderParent> wrapper = new LambdaQueryWrapper<>();
//                OrderParent orderParent = orderParentMapper.selectOne(wrapper.eq(OrderParent::getPayOrderNo, payNo));
//                Integer status = orderParent.getStatus();
//                if(!OrderParentStatusEnum.WAIT_PAY.getCode().equals(status)){
//                    throw new LaiKeAPIException(ERRCODE_CALLBACKPROCESSED,"订单回调已处理,勿重复处理");
//                }
//                PaymentParams paymentParams = new PaymentParams();
//                paymentParams.setStoreId(orderParent.getStoreId());
//                paymentParams.setPayType(ORDERPAYTYPE_MINI_WECHAT);
//                WechatConfigInfo wechatConfigInfo = getWechatConfigInfo(paymentParams);
//                params.put("storeId",orderParent.getStoreId());
//                params.put("wechatConfig",wechatConfigInfo);
//                //不存在的情况直接返回错误
//                if (StringUtils.isBlank(wechatConfigInfo.getKey())) {
//                    logger.info("微信v2回调失败:{}", wechatConfigInfo);
//                }
//                params.put("key", wechatConfigInfo.getKey());
//                logger.info("key:{}", wechatConfigInfo.getKey());
//                params.put("notifyData", weChatXml);
//                Map map = payBack(params);
//                logger.info("微信v2回调成功 处理结果：{}", map);
//                return WXPayConstants.SUCCESS;
//            } else {
//                logger.info("微信v2回调失败2:{}", returnMsg);
//                return WXPayConstants.FAIL;
//            }
//        } catch (Exception e) {
//            logger.error("微信v2回调失败", e);
//            return WXPayConstants.FAIL;
//        }
//    }
//
//    @Transactional
//    @Override
//    public Map<String, Object> payBack(Map params) throws LaiKeAPIException {
//        Map resultMap = Maps.newHashMap();
//        try {
//            int storeId = MapUtils.getInteger(params, "storeId");
//            String notifyData = MapUtils.getString(params, "notifyData");
//            WechatConfigInfo wechatConfig = (WechatConfigInfo) params.get("wechatConfig");
//            WXPay wxpay = new WXPay(wechatConfig);
//            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);
//            logger.info("回调notifyMap-{}", JSONObject.toJSON(notifyMap));
//            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
//                logger.info("回调notifyMap-{}", JSONObject.toJSON(notifyMap));
//                String payOrderNo = DataUtils.getStringVal(params, "payNo");
//                //要更新子单已经订单子项
//                BalancePayServiceImpl balancePayService = SpringHelper.getBeanInfo(BalancePayServiceImpl.class);
//                Date now = new Date();
//                LambdaQueryWrapper<OrderParent> wrapper = new LambdaQueryWrapper<>();
//                OrderParent updateOrderParent = orderParentMapper.selectOne(wrapper.eq(OrderParent::getPayOrderNo, payOrderNo));
//                balancePayService.updateOrderAndDetail(updateOrderParent.getUserId(), now,updateOrderParent,updateOrderParent.getPayType());
//                updateOrderParent.setStatus(OrderParentStatusEnum.WAIT_SEND.getCode());
//                orderParentMessageService.addOrderParentMessageAndPhoto(updateOrderParent.getUserId(),storeId, OrderParentMessageType.ORDER_PAY_SUCCESS.getCode(), updateOrderParent.getOrderParentNo(), OrderParentStatusEnum.WAIT_SEND.getCode(),"支付成功 支付方式: 微信支付",null);
//                //更新母订单
//                orderParentService.updateById(updateOrderParent);
//                logger.info("回调订单处理成功 母单号:{}",updateOrderParent.getOrderParentNo());
//            } else {
//                // 签名错误，如果数据里没有sign字段，也认为是签名错误
//                logger.error("微信支付支付回调失败：签名错误");
//                throw new LaiKeAPIException(API_OPERATION_FAILED, "微信回调失败", "payBack");
//            }
//        } catch (Exception e) {
//            logger.error("微信回调失败", e);
//            throw new LaiKeAPIException(API_OPERATION_FAILED, "微信回调失败", "payBack");
//        }
//        return resultMap;
//    }
//
//}
